/// Includes system
#include <cstdio>
#include <cstdlib>
/// Includes projects
#include "../common/framework.h"
#include "../common/deviceSelect.h"
#include "svmTrain.h"
#include "svmTrainConfig.h"
#include "svmTrainData.h"

int main( const int argc, const char** argv)  {
	printf("%s Starting...\n",argv[0]);
	int devID = chooseLargestGPU(true);

	svmTrainConfig* config = new svmTrainConfig();
	svmTrainData* trainingData = new svmTrainData();
	svmTrain* smo = new svmTrain(config, trainingData);

	/// parse command
	config->parseCommand(argc,argv);
	/// read training data
	trainingData->readSvm(config->trainingFilename);
	/// evaluate parameters
	config->checkParam(trainingData->nDimension);
	
	/// start training
	if(config->multi == OvsA) {
		trainingData->genOACode();
		switch(config->kType) {
			case GAUSSIAN:	smo->train<OvsA, GAUSSIAN>(); break;
			case LINEAR:	smo->train<OvsA, LINEAR>(); break;
			case POLYNOMIAL:smo->train<OvsA, POLYNOMIAL>(); break;
			case SIGMOID:	smo->train<OvsA, SIGMOID>(); break;
		}
	}
	else if(config->multi == OvsO) {
		trainingData->genOOCode();
		switch(config->kType) {
			case GAUSSIAN:	smo->train<OvsO, GAUSSIAN>(); break;
			case LINEAR:	smo->train<OvsO, LINEAR>(); break;
			case POLYNOMIAL:smo->train<OvsO, POLYNOMIAL>(); break;
			case SIGMOID:	smo->train<OvsO, SIGMOID>(); break;
		}
	} else {
		exit(0);
	}

	/// write model file
	smo->printModel();
	/// clean training result (Alpha)
	smo->cleanTrainingResult();

	/// clean training data
	trainingData->cleanData();
	delete smo;
	delete config;
	delete trainingData;
	//system("PAUSE");
	return 0;
}